import os
import subprocess
import time
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import Paginator, PageNotAnInteger
from django.http import JsonResponse
from django.shortcuts import render, redirect
from django.views import View

from userapp.users.models import UserModel, CustomModel
from videoapp.videos.models import VideoModel
from yl_video import dev


# Create your views here.3

@login_required(login_url='/users/login/')
def index(request):
    return render(request, 'welcom.html')


# 获取视频时长
# ffmpeg -ss 00:00:05 -i 2022-10-27_21-12-48.mp4 -vframes 1 output.jpg # 截取05秒的时间段，获得一张图片叫做output
# 获取某个视频的时长
# ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -i 2022-10-27_21-12-48.mp4


def run_cmd(cmd1, cmd2):
    """运行命令"""
    flag1 = False  # 第一个命令是否成功的标记
    flag2 = False  # 第二个命令是否成功的标记
    play_time = '0'
    result1 = subprocess.run(cmd1, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf-8', shell=True)
    result2 = subprocess.run(cmd2, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf-8', shell=True)

    if result1.returncode == 0:  # 执行成功
        print('播放时长命令完成')
        flag1 = True
        long_time = result1.stdout  # 命令的正常输出结果
        # 需要截取整数部分
        play_time = long_time[:long_time.find('.')]  # 返回播放时长的数值
    else:
        print('播放时长命令执行错误')
        print(result1)
    if result2.returncode == 0:
        print('截取图片命令完成')
        flag2 = True
    else:
        print('截取图片命令执行错误')
        print(result2)

    if flag1 and flag2:
        return True, int(play_time)
    else:
        return False, int(play_time)


def video_operator(video_id, video_path, img_path):
    """
    视频处理,就是拼凑好两条ffmpeg的命令
    :param video_id: 视频的ID ，因为需要根据ID修改数据库表
    :param video_path: 视频的路径
    :param img_path:  视频预览图片存放路径
    :return:
    """
    # 拼凑播放时长的命令
    cmd1 = f'ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -i {video_path}'
    # 拼凑截取图片的命令，固定：截取视频中第5秒图片
    cmd2 = f'ffmpeg -ss 00:00:05 -i {video_path} -vframes 1 {img_path}'
    print(cmd1)
    print(cmd2)
    result = run_cmd(cmd1, cmd2)  # 使用单独的进程执行命令
    time.sleep(5)
    # 如果命令正常执行，则修改数据库中video记录（增加预览图片路径和播放时长）
    if result[0]:
        # 得到图片的名字
        image_name = os.path.basename(img_path)
        # 得到视频播放时长
        play_time = '%02d:%02d' % (int(result[1] / 60), result[1] % 60)
        # 修改数据库的数据，注意：is_success修改为Ture
        VideoModel.objects.filter(id=video_id).update(video_icon=image_name, running_time=play_time, is_success=True)


# 视频上传试图
class VideosView(LoginRequiredMixin, View):
    """这里的LoginRequiredMixin是判断下面函数是在登陆的情况才执行的，View继承父类"""

    def post(self, request):
        # 标题
        title = request.POST['title']
        # 视频描述
        remark = request.POST['remark']
        # 视频文件
        video_file = request.FILES['video']
        if not video_file:
            return JsonResponse({"error": "No video file"}, status=400)
        # 我们需要把上传视频的用户保存下来，我们使用Django自带的保存方式
        current_user = request.user
        # 把接受到的数据保存到数据库中去
        video = VideoModel.objects.create(title=title, remark=remark, video_file=video_file, user=current_user)
        # 接下来，截取视频预览图片 和获取视频播放时长
        # 视频的预览图片名字采用: id +.jpg 的规则
        img_path = os.path.join(dev.BASE_DIR, 'media', format(f'{video.id}.jpg'))
        # id   文件位置   照片位置
        video_operator(video.id, video.video_file.path, img_path)
        return render(request, 'success.html')


class VideoListVIew(LoginRequiredMixin, View):

    def get(self, request, operator):
        # 调用下一个函数
        if operator == 'mylist':
            return self.my_video_list(request)
        elif operator == 'otherlist':
            return self.videos_of_user(request)

    def videos_of_user(self, request):
        # 查看关注用户的列表
        uid = int(request.GET.get('uid'))
        print(uid,'-------------')
        user = UserModel.objects.get(id=uid)
        print(user,'-------+----')
        # 查看用户是否上传视频
        videos = VideoModel.objects.filter(is_success=True, user_id=uid)
        # 往模板中传入数据
        return render(request, 'user_video_list.html',
                      {'video_list': videos, 'my_user': user})

    def my_video_list(self, request):
        """我的视频列表"""
        # 查询
        videos = VideoModel.objects.filter(user_id=request.user.id, is_success=True)
        # 分页考虑，注意:请求地址中？中，需要携带一个参数：page代表页号
        page_num = request.GET.get('page', 1)
        # 只显示4条数据
        paginator = Paginator(videos, 4)
        try:
            # 创建page对象，某一页的数据，一个page对象代表一页显示的数据
            page = paginator.page(page_num)
        except PageNotAnInteger:  # 参数错误造成的
            # 如果参数错误，默认访问第一页
            page = paginator.page(1)
        except Exception:
            # 如果参数错误我们就直接返回最后一页的数据
            page = paginator.page(paginator.num_pages)
        return render(request, 'my_video_list.html', {
            'video_page': page,  # 第一个
            'page_range': paginator.page_range,  # 范围
            'current_page': page.number  # 当前页
        })


# 视频播放
@login_required(login_url='/users/login/')  # 这里是判断是否登陆的用户状态
def play_video(request):
    vid = int(request.GET.get('id'))
    # 判断查询到的这个ID跟数据库中的是否一样
    video = VideoModel.objects.get(id=vid)
    print(video.video_file.url)
    # 修改数据库中的值
    VideoModel.objects.filter(id=vid).update(running_count=video.running_count + 1)
    return JsonResponse({"data": "OK"})


# 删除视频
@login_required(login_url='/users/login/')
def delete_video(request):
    vid = int(request.GET.get('id'))
    VideoModel.objects.filter(id=vid).delete()
    # 继续重定向到视频列表页面
    return redirect('/videos/vid/mylist/')
